package com.example.module.linker;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.method.BaseKeyListener;
import android.util.Log;
import android.widget.Toast;

import com.example.entity.Const;
import com.example.persistence.ImageActivity;
import com.example.persistence.MyApplication;
import com.example.util.FileUtil;
import com.facebook.Session;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.android.Util;


@SuppressWarnings("deprecation")
public class FacebookLink {
	private static final String[] PERMISSIONS = new String[] { "publish_stream", "read_stream", "offline_access", "photo_upload" };
//	private static final String[] PERMISSIONS = new String[] { "publish_stream", "read_stream", "offline_access", "user_photos", "publish_checkins", "photo_upload" };
	private Facebook facebook;
	private MyApplication application;
	private ImageActivity activity;
	private AsyncTask<PostJob, Integer, String> postTask;
	private ProgressDialog progressDialog;
	
	public FacebookLink(ImageActivity activity) {
		this.activity = activity;
		this.application = activity.application;
		this.facebook = new Facebook(Const.FACEBOOK_APP_ID
				, activity.application.getFacebookAccessToken()
				, activity.application.getFacebookSession());
		
		progressDialog = new ProgressDialog(activity);
		progressDialog.setMessage("전송 중... ");
		progressDialog.setCancelable(false);
	}
	
	private void authorize(final AuthorizeListener authorizeListener) {
		facebook.authorize(activity, PERMISSIONS, new DialogListener() {

			@Override
			public void onComplete(Bundle values) {
				String accessToken = facebook.getAccessToken();
				Session session = facebook.getSession();
				Log.e("FacebookLink authorize", "accessToken=" + accessToken);
				Log.e("FacebookLink authorize", "session=" + session);
				application.setFacebookAccessToken(accessToken);
				application.setFacebookSession(session);
				authorizeListener.doPublish();
			}

			@Override
			public void onFacebookError(FacebookError error) {
				error.printStackTrace();
			}

			@Override
			public void onError(DialogError e) {
				e.printStackTrace();
			}

			@Override
			public void onCancel() {
				
			}
		});
	}
	
	private interface AuthorizeListener {
		public void doPublish();
	}
	
	public void publish(final String message) {
		Log.e("FacebookLink publish", "isSessionValid=" + facebook.isSessionValid());
		
		PostJob postJob = new PostJob(message);
		publishJob(postJob);
	}
	
	public void publish(final String message, final File image) {
		Log.e("FacebookLink publish", "isSessionValid=" + facebook.isSessionValid());
		
		PostJob postJob = new PostJob(message, image);
		publishJob(postJob);
	}
	
	private void publishJob(final PostJob postJob) {
		postTask = new AsyncTask<PostJob, Integer, String>(){

			@Override
			protected void onPreExecute() {
				progressDialog.show();
				super.onPreExecute();
			}
			
			@Override
			protected String doInBackground(PostJob... posts) {
				Log.e("doInBackground", "posts.length=" + posts.length);
				
				for (PostJob post : posts) {
					Log.e("doInBackground", "post=" + post);
					if (post == null)
						continue;
					
					if (post.getImage() != null && post.getImage().isFile())
						publishPhoto(post.getMessage(), post.getImage());
					else
						publishStatus(post.getMessage());
				}
				
				return null;
			}

			@Override
			protected void onPostExecute(String result) {
				Log.e("onPostExecute", "result=" + result);
//				Toast.makeText(activity, "트위터 포스팅 완료", Toast.LENGTH_SHORT).show();
			};
		};
		
		if (!facebook.isSessionValid()) {
			authorize(new AuthorizeListener() {
				@Override
				public void doPublish() {
					postTask.execute(postJob);
				}
			});
		}
		else {
			postTask.execute(postJob);
		}
	}
	
	private void publishStatus(String message){
		Log.e("publishStatus", "message=" + message);
		
		AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner (facebook);

		Bundle parameters = new Bundle ();
		parameters.putString (Facebook.TOKEN, facebook.getAccessToken());
		parameters.putString ("message", message);

		mAsyncRunner.request ("me/feed", parameters, "POST", new SampleUploadListener(), null);
	}
	
	private void publishPhoto(String message, File image) {
		Log.e("publishPhoto", "message=" + message + " image=" + image.isFile());
		
		AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner (facebook);

		Bundle parameters = new Bundle ();
		parameters.putString (Facebook.TOKEN, facebook.getAccessToken());
		parameters.putString ("message", message);
		parameters.putByteArray ("source", FileUtil.getBytesFromFile(image));

		mAsyncRunner.request ("me/photos", parameters, "POST", new SampleUploadListener(), null);
	}
	
//	@Override
//	public void onActivityResult(int requestCode, int resultCode, Intent data) {
//		super.onActivityResult(requestCode, resultCode, data);
//
//		facebook.authorizeCallback(requestCode, resultCode, data);
//	}
	
	public class SampleUploadListener extends BaseKeyListener implements RequestListener {

		@Override
		public int getInputType() {
			return 0;
		}

		@Override
		public void onComplete(String response, Object state) {
			try {
				progressDialog.dismiss();
				
	            // process the response here: (executed in background thread)
	            Log.d("Facebook-Example", "Response: " + response.toString());
	            JSONObject json = Util.parseJson(response);
	            final String id = json.getString("id");
	            
	            activity.runOnUiThread(new Runnable() {
					
					@Override
					public void run() {
						Toast.makeText(activity, "성공적으로 공유했습니다. (게시글 id:" + id+ ")", Toast.LENGTH_SHORT).show();		
					}
				});

	            // then post the processed result back to the UI thread
	            // if we do not do this, an runtime exception will be generated
	            // e.g. "CalledFromWrongThreadException: Only the original
	            // thread that created a view hierarchy can touch its views."

	        } catch (JSONException e) {
	            Log.w("Facebook-Example", "JSON Error in response");
	        } catch (FacebookError e) {
	            Log.w("Facebook-Example", "Facebook Error: " + e.getMessage());
	        }			
		}

		@Override
		public void onIOException(IOException e, Object state) {
		}

		@Override
		public void onFileNotFoundException(FileNotFoundException e, Object state) {
		}

		@Override
		public void onMalformedURLException(MalformedURLException e, Object state) {
		}

		@Override
		public void onFacebookError(FacebookError e, Object state) {
		}
	}
}
